import serial
import time
import threading

class RTKDriver:
    '''
        串口驱动
    '''
    def __init__(self,port,baudrate=115200,timeout=0,buffer_len=200,callback=None):
        ''' 初始化 '''

        self.buffer={}
        self.buffer_len=buffer_len
        self.OpenPort(port,baudrate,timeout)
        self.callback=callback
        '''开启接收线程'''
        _recv_thread=threading.Thread(target=self._Recv,args=())
        _recv_thread.setDaemon(True)
        _recv_thread.start()

    def OpenPort(self,port,baudrate=115200,timeout=0):
        '''打开串口'''
        try:
            self.port=serial.Serial(port=port,baudrate=baudrate,timeout=timeout)
            return True
        except:
            return False

    def ClosePort(self):
        '''关闭串口'''
        try:
            self.port.close()
            return True
        except:
            return False

    def ClearBuffer(self):
        '''清空buffer'''
        self.buffer={}


    def _Recv(self):
        '''获取数据'''
        while True:
            '''解析串口数据'''
            time.sleep(0.02)
            if self.port.in_waiting: 
                time.sleep(0.05)
                try:
                    line=self.port.readline()
                    line=line.decode('utf-8').strip()
                    if not (line.startswith('INFO') and line.endswith('RTCMDATA')):continue
                    line=line[0:line.find('MESSAGE')]
                    target = {"IP": "", "MODE": "", "UTC": "", "RSSI": "", "RMS": "", "LLA": [0.0] * 3, "XYZ": [0.0] * 3,
                            "MSG": "","DIR":0.0,"SPD":0.0, "DELAY": 0.0, "STAMP": 0.0}
                    parts = line.split(',')
                    for part in parts:
                        if part.startswith('IP'):
                            target['IP'] = part.strip('IP')
                        elif part.startswith('UTC'):
                            target['UTC'] = part.strip('UTC')
                        elif part.startswith('MODE'):
                            target['MODE'] = part.strip('MODE')
                        elif part.startswith('RSSI'):
                            target['RSSI'] = int(part.strip('RSSI'))
                        elif part.startswith('RMS'):
                            target['RMS'] = float(part.strip('RMS'))
                        elif part.startswith('DIR'):
                            target['DIR'] = float(part.strip('DIR'))
                        elif part.startswith('SPD'):
                            target['SPD'] = float(part.strip('SPD'))    
                        elif part.startswith('GPSX'):
                            target['LLA'][0] = float(part.strip('GPSX')) / 100000000.0
                        elif part.startswith('GPSY'):
                            target['LLA'][1] = float(part.strip('GPSY')) / 100000000.0
                        elif part.startswith('GPSZ'):
                            target['LLA'][2] = float(part.strip('GPSZ'))
                        elif part.startswith('X'):
                            target['XYZ'][0] = float(part.strip('X'))
                        elif part.startswith('Y'):
                            target['XYZ'][1] = float(part.strip('Y'))
                        elif part.startswith('Z'):
                            target['XYZ'][2] = float(part.strip('Z'))
                    target['STAMP']=time.time()
                    uid=parts[2].strip('UID')
                    if not uid in self.buffer: self.buffer[uid]=[]
                    self.buffer[uid].append(target)
                    if len(self.buffer[uid])>1: self.buffer[uid][-1]['DELAY']=self.buffer[uid][-1]['STAMP']-self.buffer[uid][-2]['STAMP']
                    if len(self.buffer[uid])>self.buffer_len: self.buffer[uid].pop(0)
                    if self.callback: self.callback()
                except:
                    pass
                
if __name__=='__main__':
    d=RTKDriver('COM3')
    while True:
        time.sleep(1)